<template>
  <el-select
    v-model="innerDays"
    multiple
    placeholder="请选择日期"
    clearable
    filterable
    collapse-tags
    collapse-tags-tooltip
    @visible-change="visible = $event"
  >
    <!-- 1. 下拉面板：日历 + 全选 -->
    <template #empty>
      <div class="calendar-panel" @click.stop>
        <!-- 全选 -->
        <div class="panel-header">
          <el-checkbox
            v-model="checkAll"
            :indeterminate="indeterminate"
            @change="(val: CheckboxValueType) => toggleAll(Boolean(val))"
          >
            全选
          </el-checkbox>
        </div>

        <!-- 2. 当月日历 -->
        <el-calendar v-model="calDate" class="only-current-month">
          <template #date-cell="{ data }">
            <div v-if="isCurrentMonth(data.date)" class="day-cell">
              <!-- 用 label 包文字 → 点数字即 toggle -->
              <el-checkbox
                :model-value="innerDays.includes(fmt(data.date))"
                @update:model-value="(v) => toggleDay(data.date, v)"
              >
                <span class="day-text">{{ data.date.getDate() }}</span>
              </el-checkbox>
            </div>
          </template>
        </el-calendar>
      </div>
    </template>

    <!-- 3. 回显省略 + tooltip -->
    <template #tag="{ tag, key }">
      <el-tooltip
        v-if="key === 0 && innerDays.length > showCount"
        :content="allText"
        placement="top"
      >
        <el-tag size="small" closable @close="removeDay(tag)">
          {{ innerDays.slice(0, showCount).join("、") }}...
        </el-tag>
      </el-tooltip>
      <el-tag
        v-else-if="key < showCount"
        size="small"
        closable
        @close="removeDay(tag)"
      >
        {{ tag }}
      </el-tag>
    </template>
  </el-select>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import {
  ElTag,
  ElTooltip,
  ElCheckbox,
  ElCalendar,
  type CheckboxValueType,
} from "element-plus";
import { format, startOfMonth, endOfMonth, isSameMonth } from "date-fns";

/* ---------------- props & emit ---------------- */
const props = withDefaults(
  defineProps<{
    modelValue: string[]; // YYYY-MM-DD
    placeholder?: string;
    showCount?: number; // 省略阈值
  }>(),
  { placeholder: "请选择日期", showCount: 2 }
);
const emit = defineEmits<{ "update:modelValue": (days: string[]) => void }>();

/* ---------------- 状态 ---------------- */
const visible = ref(false);
const calDate = ref(new Date()); // 日历当前页（默认本月）

/* ---------------- 双向绑定 ---------------- */
const innerDays = computed<string[]>({
  get: () => props.modelValue,
  set: (v) => emit("update:modelValue", v),
});

/* ---------------- 当月日期列表 ---------------- */
const currentMonthDays = computed<string[]>(() => {
  const arr: string[] = [];
  const start = startOfMonth(calDate.value);
  const end = endOfMonth(calDate.value);
  for (let d = start; d <= end; d = new Date(d.setDate(d.getDate() + 1))) {
    arr.push(fmt(d));
  }
  return arr;
});

/* ---------------- 全选逻辑 ---------------- */
const checkAll = computed({
  get: () =>
    currentMonthDays.value.length > 0 &&
    currentMonthDays.value.every((d) => innerDays.value.includes(d)),
  set: (v) => toggleAll(v),
});
const indeterminate = computed(() => {
  const n = innerDays.value.filter((d) =>
    currentMonthDays.value.includes(d)
  ).length;
  return n > 0 && n < currentMonthDays.value.length;
});

function toggleAll(checked: boolean) {
  const otherDays = innerDays.value.filter(
    (d) => !currentMonthDays.value.includes(d)
  );
  innerDays.value = checked
    ? [...otherDays, ...currentMonthDays.value]
    : otherDays;
}

/* ---------------- 单天切换 ---------------- */
function toggleDay(date: Date, checked: boolean) {
  const str = fmt(date);
  const set = new Set(innerDays.value);
  checked ? set.add(str) : set.delete(str);
  innerDays.value = Array.from(set).sort();
}

function removeDay(day: string) {
  innerDays.value = innerDays.value.filter((d) => d !== day);
}

/* ---------------- 工具 ---------------- */
const fmt = (d: Date) => format(d, "yyyy-MM-dd");
const isCurrentMonth = (d: Date) => isSameMonth(d, calDate.value);

/* ---------------- 回显文本 ---------------- */
const allText = computed(() => innerDays.value.join("、"));
</script>

<style scoped>
.calendar-panel {
  width: 320px;
  padding: 8px;
  .panel-header {
    text-align: left !important;
    .el-checkbox {
      margin-left: 15px;
    }
  }
}
.only-current-month :deep(.el-calendar__header) {
  display: none;
}
.only-current-month :deep(.el-calendar-table td:not(.current)) {
  visibility: hidden;
  height: 0;
  padding: 0;
  border: none;
}
.day-cell {
  display: flex;
  align-items: center;
  height: 32px !important;
}
.day-text {
  margin-left: 6px;
}
/* 1. 去掉格子线 */
.only-current-month :deep(.el-calendar-table td) {
  border: none !important;
  background: transparent !important;
}
.only-current-month :deep(.el-calendar-table td:hover) {
  background: transparent !important;
}

.only-current-month :deep(.el-calendar-day) {
  height: 52px; /* 自定义高度 */
  padding: 2px 4px; /* 可选：紧缩内边距 */
}

.only-current-month :deep(.el-calendar__body) {
  padding: 0 10px; /* 想改多少写多少 */
}

/* 2. 扩大点击区域 */
.day-cell {
  display: flex;
  align-items: center;
  height: 100%;
  width: 100%;
  cursor: pointer;
}
.day-cell :deep(.el-checkbox) {
  width: 100%;
  height: 100%;
  padding: 4px; /* 扩大可点区域 */
}
.day-cell :deep(.el-checkbox__label) {
  padding-left: 4px !important; /* 原来是 8px */
  line-height: 1;
}
.day-text {
  margin-left: 0px;
  user-select: none;
}
</style>
